﻿// -----------------------------------------------------------------------
// <copyright file="Words_Legacy.cs" company="G.W. van der Vegt">
// SharpForth is inspired by JonesForthInC v1.48 and bb4wForth.
// </copyright>
// -----------------------------------------------------------------------

namespace SharpForth
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Threading;

    /// <summary>
    /// This static class contains all built-in Forth Words.
    /// </summary>
    public static partial class Words
    {
        #region Legacy Forth Words

        /// <summary>
        /// 1027 (n1 n2 n3 -- n2 n1 n2)
        /// </summary>
        [WordName("-ROT")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( x1 x2 x3 -- x3 x1 x2 )")]
        internal static Lazy<DictionaryEntry> NROT = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("-ROT", 0, delegate
             {
                 Int32 n3 = Forth.POP_P_STACK();
                 Int32 n2 = Forth.POP_P_STACK();
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n3);
                 Forth.PARAM_STACK.Push(n1);
                 Forth.PARAM_STACK.Push(n2);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// (n1 -- n1+2)
        /// </summary>
        [WordName("2+")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 -- n1+2 )")]
        internal static Lazy<DictionaryEntry> INCR2 = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("2+", 0, delegate
             {
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 + 2);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// (n1 -- n1-2)
        /// </summary>
        [WordName("2-")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 -- n1-2 )")]
        internal static Lazy<DictionaryEntry> DECR2 = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("2-", 0, delegate
             {
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 - 2);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1073 (n1 -- n1+4)
        /// </summary>
        [WordName("4+")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 -- n1+4 )")]
        internal static Lazy<DictionaryEntry> INCR4 = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("4+", 0, delegate
             {
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 + 4);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1077 (n1 -- n1-4)
        /// </summary>
        [WordName("4-")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 -- n1-4 )")]
        internal static Lazy<DictionaryEntry> DECR4 = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("4-", 0, delegate
             {
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 - 4);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1157 (n1 n2 -- 1 if n1 &lt;= n2 | 0 if n1 &gt; n2)
        /// </summary>
        [WordName("<=")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 n2 -- -1 if n1 <= n2 | 0 if n1 > n2 )")]
        internal static Lazy<DictionaryEntry> LE = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("<=", 0, delegate
             {
                 Int32 n2 = Forth.POP_P_STACK();
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 <= n2 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1160 (n1 n2 -- 1 if n1 &gt;= n2 | 0 if n1 &lt; n2)
        /// </summary>
        [WordName(">=")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 n2 -- -1 if n1 >= n2 | 0 if n1 < n2 )")]
        internal static Lazy<DictionaryEntry> GE = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry(">=", 0, delegate
             {
                 Int32 n2 = Forth.POP_P_STACK();
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 >= n2 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1191 (n1 -- 1 if n1 &lt;= 0 | 0 if n1 &gt; 0)
        /// </summary>
        [WordName("0<=")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 -- flag )")]
        internal static Lazy<DictionaryEntry> ZLE = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("0<=", 0, delegate
             {
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 <= 0 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1194 (n1 -- 1 if n1 &gt;= 0 | 0 if n1 &lt; 0)
        /// </summary>
        [WordName("0>=")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 -- flag )")]
        internal static Lazy<DictionaryEntry> ZGE = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("0>=", 0, delegate
             {
                 Int32 n1 = Forth.POP_P_STACK();

                 Forth.PARAM_STACK.Push(n1 >= 0 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1293
        /// </summary>
        [WordName("LIT")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> LIT = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("LIT", 0, delegate(DictionaryEntry self)
             {
                 //! Implemented inside Invoke()/Execute().

             }), true);

        /// <summary>
        /// 2507
        /// </summary>
        [WordName("LITSTRING")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> LITSTRING = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("LITSTRING", 0, delegate
             {
                 //! Implemented inside Invoke()/Execute().
             }), true);

        /// <summary>
        /// 1326 ( )
        /// </summary>
        [WordName("-!")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> SUBSTORE = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("-!", 0, delegate
             {
                 Int32 adr = Forth.POP_P_STACK(); // address to fetch
                 Int32 dat = Forth.POP_P_STACK();

                 switch (Forth.A2M(adr))
                 {
                     case Forth.MEM_DEF:
                         Forth.Dictionary[Forth.A2I(adr)].Definition[Forth.A2D(adr)] -= dat;
                         break;
                     case Forth.MEM_RSP:
                         Forth.DoOutput("MemoryType 1 Not Implemented");
                         return;
                     case Forth.MEM_PRM:
                         Forth.DoOutput("MemoryType 2 Not Implemented");
                         return;
                     case Forth.MEM_WRD:
                         Forth.STRING_BUFFER[Forth.A2A(adr)] -= (Char)dat;
                         break;
                 }

                 Forth.NEXT();
             }), true);


        /// <summary>
        /// 1406 ( --- DP) Must be located after BRANCH/LIT
        /// </summary>
        [WordName("DP")]
        [WordSet(WordSets.LEGACY)]
        [Depends("DOCOL")]
        [Depends("LIT")]
        [Depends("BRANCH")]
        [Depends("EXIT")]
        [Syntax("( -- addr )")]
        internal static Lazy<DictionaryEntry> DP = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("DP", 0, new Int32[]
                {
                    Forth.Locate("DOCOL"),

                    Forth.Locate("LIT"),
                    ((Forth.Dictionary.IndexOf(Forth.Dictionary.Last()) + 1) << 16) + 24,
                    
                    Forth.Locate("BRANCH"), // Jump over DP
                    12,
                    //
                    Forth.Locate("LIT"),
                    Forth.DP,
                    //
                    Forth.Locate("EXIT")
                }), true);


        /// <summary>
        /// 1407 ( --- LATEST) Must be located after BRANCH/LIT
        /// </summary>
        [WordName("LATEST")]
        [WordSet(WordSets.LEGACY)]
        [Depends("DOCOL")]
        [Depends("LIT")]
        [Depends("BRANCH")]
        [Depends("EXIT")]
        [Syntax("( -- addr )")]
        internal static Lazy<DictionaryEntry> LATEST = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("LATEST", 0, new Int32[]
                {
                    Forth.Locate("DOCOL"),

                    Forth.Locate("LIT"),
                    ((Forth.Dictionary.IndexOf(Forth.Dictionary.Last()) + 1) << 16) + 24,
                    
                    Forth.Locate("BRANCH"), // Jump over LATEST
                    12,
                    //
                    Forth.Locate("LIT"),
                    Forth.LATEST,
                    //
                    Forth.Locate("EXIT")
                }), true);
                
        /// <summary>
        /// 1411 ( --- BUILTIN)
        /// </summary>
        [WordName("BUILT-IN")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- addr )")]
        internal static Lazy<DictionaryEntry> BUILTIN = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("BUILT-IN", 0, delegate
             {
                 Forth.PARAM_STACK.Push(Forth.BUILT_IN);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1412 ( --- CURRKEY)
        /// </summary>
        [WordName("CURRKEY")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- n )")]
        internal static Lazy<DictionaryEntry> CURRKEY = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("CURRKEY", 0, delegate
             {
                 Forth.PARAM_STACK.Push(Forth.CURRKEY);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1437 ( --- DOCOL)
        /// </summary>
        [WordName("DOCOL")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> DOCOL = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("DOCOL", 0, delegate
             {
                 Forth.PUSH_R_STACK(Forth.esi);

                 Forth.eax += 4;
                 Forth.esi = Forth.eax;

                 //! Was Forth.NEXT();
                 //Forth.EXECUTE();
             }), true);

        /// <summary>
        /// 1498 ( )
        /// </summary>
        [WordName("RSP@")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> RSPFETCH = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("RSP@", 0, delegate
             {
                 Forth.PARAM_STACK.Push(((Forth.RETURN_STACK.Count - 1) << 2) % Forth.MEM_RSP);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1506 ( )
        /// </summary>
        [WordName("RDROP")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> RDROP = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("RDROP", 0, delegate
             {
                 Forth.POP_R_STACK();

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1517 ( )
        /// </summary>
        [WordName("DSP@")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> DSPFETCH = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("DSP@", 0, delegate
             {
                 Forth.PARAM_STACK.Push(((Forth.PARAM_STACK.Count - 1) << 2) % Forth.MEM_PRM);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1526 ( )
        /// </summary>
        [WordName("DROPALL")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> DROPALL = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("DROPALL", 0, delegate
             {
                 Forth.PARAM_STACK.Clear();

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1895 ( )
        /// </summary>
        [WordName("NUMBER")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> NUMBER = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("NUMBER", 0, delegate
             {
                 //! Excpect a STRING_BUFFER Pointer.
                 Int32 length = Forth.POP_P_STACK();
                 Int32 start = Forth.POP_P_STACK() & Forth.MTM;
                 Int32 num;

                 Int32 cnt = Forth.BaseToDecimal(Forth.FetchWord(start, length), Forth.BASE, out num);

                 Forth.PARAM_STACK.Push(num);
                 if (cnt != 0)
                 {
                     Forth.DoOutput(Forth.ErrorMarker + "Invalid Number", true);
                 }
                 Forth.PARAM_STACK.Push(cnt);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 2024
        /// </summary>
        [WordName(">CFA")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> TCFA = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry(">CFA", 0, delegate
             {
                 // CFA == DFA == FIND == >BODY
                 Forth.PUSH_P_STACK(Forth.POP_P_STACK());

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 2053
        /// </summary>
        [WordName(">DFA")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> TDFA = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry(">DFA", 0, delegate
             {
                 // CFA == DFA == FIND == >BODY
                 Forth.PARAM_STACK.Push(Forth.POP_P_STACK());

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 2357
        /// </summary>
        [WordName("HIDDEN")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> HIDDEN = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("HIDDEN", 0, delegate
             {
                 Int32 ndx = Forth.POP_P_STACK();

                 Forth.Dictionary[Forth.A2I(ndx)].ToggleHide();

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 2363
        /// </summary>
        [WordName("HIDE")]
        [WordSet(WordSets.LEGACY)]
        [Depends("WORD")]
        [Depends("EXIT")]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> HIDE = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("HIDE", 0, delegate
             {
                 // Get the word (after HIDE).
                 WORD.Value.Invoke();

                 //! Excpect a STRING_BUFFER Pointer.
                 Int32 length = Forth.POP_P_STACK();
                 Int32 start = Forth.POP_P_STACK() & Forth.MTM;

                 // Look up in the dictionary.
                 Int32 ndx = Forth.Locate(Forth.FetchWord(start, length));

                 // Set F_HIDDEN flag.
                 Forth.Dictionary[Forth.A2I(ndx)].ToggleHide();

                 EXIT.Value.Invoke();
             }), true);

        /// <summary>
        /// 2691
        /// </summary>
        [WordName("INTERPRET")]
        [WordSet(WordSets.LEGACY)]
        [Depends("WORD")]
        [Depends("LIT")]
        [Depends(",")]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> INTERPRET = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("INTERPRET", 0, delegate
             {
                 //! Fixup for ." not aquiring the appended \n 
                 //! So WORD is called blocking and no OK prompt is printed!

                 if ((!Forth.DoInputAvailable() && Forth.input.Count == 0) ||
                     (Forth.input.Count == 1 && Forth.input.Peek() == '\n'))
                 {
                     Forth.DoOutput(Forth.OkMarker);
                     Forth.input.Clear();
                 }

                 //! Call Word
                 WORD.Value.Invoke();

                 Int32 length = Forth.POP_P_STACK();
                 Int32 start = Forth.POP_P_STACK() & Forth.MTM;

                 // Fetch and Remove word from word_buffer.
                 String word = Forth.FetchWord(start, length, true);

                 Int32 ndx = Forth.Locate(word);

                 if (ndx == 0)
                 {
                     // Debugger.Break();
                 }
                 if (ndx != -1)
                 {
                     //! Forth Word

                     //Debug.Print("> {0}", Dictionary[Forth.A2I(ndx)].Name);

                     switch (Forth.STATE)
                     {
                         case Forth.IMMEDIATE_MODE:
                             //! Execute.
                             Forth.Dictionary[Forth.A2I(ndx)].Invoke();
                             break;

                         case Forth.COMPILE_MODE:
                             if ((Forth.Dictionary[Forth.A2I(ndx)].Flags & Forth.FORTH_IMMED_MASK) == Forth.FORTH_IMMED_MASK)
                             {
                                 //! Execute if F_IMMED.
                                 Forth.Dictionary[Forth.A2I(ndx)].Invoke();
                             }
                             else
                             {
                                 //! Compile into Definition.
                                 Forth.PARAM_STACK.Push(ndx);
                                 COMMA.Value.Invoke();
                             }
                             break;
                     }
                 }
                 else if (length != 0)
                 {
                     Int32 num;

                     //Literal
                     switch (Forth.STATE)
                     {
                         case Forth.IMMEDIATE_MODE:
                             try
                             {
                                 //! Execute (ie Push Literal onto Parameter Stack).
                                 {
                                     Int32 cnt = Forth.BaseToDecimal(word, Forth.BASE, out num);

                                     Forth.PARAM_STACK.Push(num);
                                     if (cnt != 0)
                                     {
                                         Forth.DoOutput(Forth.ErrorMarker + "Invalid Number", true);
                                     }
                                 }
                             }
                             catch (FormatException e)
                             {
                                 Forth.DoOutput(String.Format(Forth.ErrorMarker + "Word not found and not convertable to a BASE {0} number.", BASE), true);
                                 Debug.Print(e.Message);
                             }
                             break;

                         case Forth.COMPILE_MODE:
                             //! Compile as LIT {Literal} into Definition.
                             Forth.PARAM_STACK.Push(Forth.Locate("LIT"));

                             COMMA.Value.Invoke();
                             {
                                 Int32 cnt = Forth.BaseToDecimal(word, Forth.BASE, out num);

                                 Forth.PARAM_STACK.Push(num);
                                 if (cnt != 0)
                                 {
                                     Forth.DoOutput(Forth.ErrorMarker + "Invalid Number", true);
                                 }
                             }
                             COMMA.Value.Invoke();

                             break;
                     }
                 }
                 else
                 {
                     //! EOF
                 }

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 2481 Needs to be located before DP &amp; BASE.
        /// </summary>
        [WordName("BRANCH")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> BRANCH = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("BRANCH", 0, delegate
             {
                 //! Implemented inside Invoke()/Execute().
             }), true);

        /// <summary>
        /// 2485
        /// </summary>
        [WordName("0BRANCH")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> ZBRANCH = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("0BRANCH", 0, delegate
             {
                 //! Implemented inside Invoke()/Execute().
             }), true);

        /// <summary>
        /// 2616 - Behavior Pointers.
        /// </summary>
        [WordName("DODOES")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> DODOES = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("DODOES", 0, delegate
             {
                 //! TODO
                 Forth.DoOutput("DODOES Not Implemented", true);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 2640 - Abort Current Input Text.
        /// </summary>
        [WordName("ABEND")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> ABEND = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("ABEND", 0, delegate
             {
                 // #warning perhaps store /0 terminated Strings so we can remove just the last. Duplicates FLUSH.
                 Forth.STRING_BUFFER.Clear();

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 4709 - Print the Return Stack.
        /// </summary>
        [WordName("PRINT-STACK-TRACE")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> PRINT_STACK_TRACE = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("PRINT-STACK-TRACE", 0, delegate
             {
                 Forth.DoOutput("( ", false);
                 foreach (Int32 ndx in Forth.RETURN_STACK.ToArray())
                 {
                     Forth.DoOutput(String.Format("{0} ", Forth.Dictionary[Forth.A2I(ndx)].Name), false);
                 }
                 Forth.DoOutput(") ", false);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 2809 - Used for DO LOOP.
        ///
        /// Set up loop control parameters with index n2|u2 and limit n1|u1. An ambiguous condition exists
        /// if n1|u1 and n2|u2 are not both the same type. Anything already on the return stack becomes
        /// unavailable until the loop-control parameters are discarded.
        /// </summary>       
        [WordName("(DO)")]
        [WordSet(WordSets.LEGACY)]
        [Depends("SWAP")]
        [Syntax("( n1|u1 n2|u2 -- ) ( R: -- loop-sys )")]
        internal static Lazy<DictionaryEntry> PAREN_DO = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("(DO)", 0, delegate
             {
                 SWAP.Value.Invoke();

                 // +/- PUSH2RSP()
                 Forth.PUSH_R_STACK(Forth.POP_P_STACK());  //limit
                 Forth.PUSH_R_STACK(Forth.POP_P_STACK());  //index
             }), true);

        /// <summary>
        /// 2824
        /// </summary>
        [WordName("(LOOP)")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( -- ) ( R:  loop-sys1 --  | loop-sys2 )")]
        internal static Lazy<DictionaryEntry> PAREN_LOOP = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("(LOOP)", 0, delegate
              {
                  //! Implemented inside Invoke()/Execute().

              }), true);

        /// <summary>
        /// 3940
        /// </summary>
        [WordName("ID.")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("ID. ( addr -- )")]
        internal static Lazy<DictionaryEntry> PRINT_ID = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("ID.", 0, delegate
              {
                  Int32 adr = Forth.POP_P_STACK();

                  Forth.DoOutput(Forth.Dictionary[Forth.A2I(adr)].Name);
              }), true);

        [WordName("+TO")]
        [WordSet(WordSets.LEGACY)]
        [Depends("WORD")]
        [Depends("FIND")]
        [Syntax("( x +TO VAL adds x to VAL )")]
        internal static Lazy<DictionaryEntry> PLUSTO = new Lazy<DictionaryEntry>(
                () => new DictionaryEntry("+TO", Forth.FORTH_IMMED_MASK, delegate
                {
                    WORD.Value.Invoke();
                    FIND.Value.Invoke();

                    Int32 adr = Forth.POP_P_STACK();

                    switch (Forth.STATE)
                    {
                        case Forth.COMPILE_MODE:
                            {
                                //! LIT
                                Forth.Dictionary[Forth.A2I(Forth.LATEST)].Definition.Add(Forth.Locate("LIT"));

                                //! Address inside VALUE
                                Forth.Dictionary[Forth.A2I(Forth.LATEST)].Definition.Add(adr + (2 << 2));

                                //! Store PSP's Top there.
                                Forth.Dictionary[Forth.A2I(Forth.LATEST)].Definition.Add(Forth.Locate("+!"));
                            }
                            break;
                        case Forth.IMMEDIATE_MODE:
                            {
                                Forth.Dictionary[Forth.A2I(adr)].Definition[2] += Forth.POP_P_STACK();
                            }
                            break;
                    }
                }), true);

        /// <summary>
        /// 1502 CFA> converts a CFA address into a Word Address (so Definition index is 0).
        /// </summary>
        [WordName("CFA>")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( 1adr -- adr or 0)")]
        internal static Lazy<DictionaryEntry> CFALOOKUP = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("CFA>", 0, delegate
             {
                 Int32 adr = Forth.POP_P_STACK();
                 Int32 ndx = Forth.A2I(adr);

                 if (ndx >= 0 && ndx < Forth.Dictionary.Count &&
                     (Forth.A2D(adr) < Forth.Dictionary[ndx].Definition.Count || Forth.A2D(adr) == 0))
                 {
                     Debug.Print("CFA> Found {0}, Length {1} Cell(s)", Forth.Dictionary[ndx].Name, Forth.Dictionary[ndx].Definition.Count);

                     adr = Forth.I2A(ndx);
                 }
                 else
                 {
                     //! Error.
                     adr = 0;
                 }

                 Forth.PUSH_P_STACK(adr);

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// 1354 ( )
        /// </summary>
        [WordName("C@C!")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( adr1 adr2 -- )")]
        internal static Lazy<DictionaryEntry> CCOPY = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("C@C!", 0, delegate
             {
                 Int32 addr1 = Forth.POP_P_STACK();
                 Int32 addr2 = Forth.POP_P_STACK();
                 Byte dat = 0;

                 switch (Forth.A2M(addr1))
                 {
                     case Forth.MEM_DEF:
                         dat = new Int32ByteUnion(Forth.Dictionary[Forth.A2I(addr1)].Definition[Forth.A2D(addr1)])[addr1 % 4];
                         break;
                     case Forth.MEM_RSP:
                         Forth.DoOutput("MemoryType 1 Not Implemented");
                         return;
                     case Forth.MEM_PRM:
                         Forth.DoOutput("MemoryType 2 Not Implemented");
                         return;
                     case Forth.MEM_WRD:
                         dat = (Byte)Forth.STRING_BUFFER[Forth.A2A(addr1)];
                         break;
                 }

                 switch (Forth.A2M(addr2))
                 {
                     case Forth.MEM_DEF:
                         Int32ByteUnion val = new Int32ByteUnion(Forth.Dictionary[Forth.A2I(addr2)].Definition[Forth.A2D(addr2)]);
                         val[addr2 % 4] = (byte)dat;
                         Forth.Dictionary[Forth.A2I(addr2)].Definition[Forth.A2D(addr2)] = val.iVal;
                         break;
                     case Forth.MEM_RSP:
                         Forth.DoOutput("MemoryType 1 Not Implemented");
                         return;
                     case Forth.MEM_PRM:
                         Forth.DoOutput("MemoryType 2 Not Implemented");
                         return;
                     case Forth.MEM_WRD:
                         Forth.STRING_BUFFER[Forth.A2A(addr2)] = (Char)dat;
                         break;
                 }

                 Forth.NEXT();
             }), true);

        /// <summary>
        /// bb4wForth n1 SHR 1
        /// </summary>
        [WordName("U2/")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( u1 -- u2 )")]
        internal static Lazy<DictionaryEntry> UTWODIV = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("U2/", 0, delegate
             {
                 UInt32 n1 = (UInt32)Forth.POP_P_STACK();

                 Forth.PUSH_P_STACK((Int32)(n1 / 2));
             }), true);

        #endregion Legacy Forth Words

        #region Problematic

        ///// <summary>
        ///// 1502 ( )
        ///// </summary>
        //[WordName("RSP!")]
        //[Syntax("( -- )")] 
        //internal static Lazy<DictionaryEntry> RSPSTORE = new Lazy<DictionaryEntry>(
        //     () => new DictionaryEntry("RSP!", 0, delegate
        //{
        //    //! TODO
        //    DoOutput("RSP! Not Implemented", true);

        //    NEXT();
        //}),true);

        ///// <summary>
        ///// 1522 ( )
        ///// </summary>
        //[WordName("DSP!")]
        //[Syntax("( -- )")] 
        //internal static Lazy<DictionaryEntry> DSPSTORE = new Lazy<DictionaryEntry>(
        //     () => new DictionaryEntry("DSP!", 0, delegate
        //{
        //    //! TODO
        //    Forth.DoOutput("DSP! Not Implemented", true);
        //
        //    Forth.NEXT();
        //}),true);

        /// <summary>
        /// 1113 (n1 n2 -- n1%n2 n1/n2)
        /// </summary>
        [WordName("U/MOD")]
        [WordSet(WordSets.LEGACY)]
        [Syntax("( n1 n2 -- n1%n2 n1/n2 )")]
        internal static Lazy<DictionaryEntry> UDIVMOD = new Lazy<DictionaryEntry>(
             () => new DictionaryEntry("U/MOD", 0, delegate
            {
                Int64 n2 = (UInt32)Forth.POP_P_STACK();
                Int64 n1 = (UInt32)Forth.POP_P_STACK();
                Int64 n3 = 0;

                Int64 n4 = Math.DivRem(n1, n2, out n3);

                Forth.PARAM_STACK.Push((Int32)n3);
                Forth.PARAM_STACK.Push((Int32)n4);

                Forth.NEXT();
            }), true);

        #endregion
    }
}
